// Copyright by LunaSec (owned by Refinery Labs, Inc)
//
// Licensed under the Business Source License v1.1
// (the "License"); you may not use this file except in compliance with the
// License. You may obtain a copy of the License at
//
// https://github.com/lunasec-io/lunasec/blob/master/licenses/BSL-LunaTrace.txt
//
// See the License for the specific language governing permissions and
// limitations under the License.
package schema

// TODO (cthompson) get this command to run as a go generate directive
// gojsonschema -p schema schema/osv.schema.json > schema/osv.go

import "fmt"
import "encoding/json"
import "reflect"

// A schema for describing a vulnerability in an open source package.
type OsvSchema struct {
	// Affected corresponds to the JSON schema field "affected".
	Affected []OsvSchemaAffectedElem `json:"affected,omitempty"`

	// Aliases corresponds to the JSON schema field "aliases".
	Aliases []string `json:"aliases,omitempty"`

	// Credits corresponds to the JSON schema field "credits".
	Credits []OsvSchemaCreditsElem `json:"credits,omitempty"`

	// DatabaseSpecific corresponds to the JSON schema field "database_specific".
	DatabaseSpecific OsvSchemaDatabaseSpecific `json:"database_specific,omitempty"`

	// Details corresponds to the JSON schema field "details".
	Details *string `json:"details,omitempty"`

	// Id corresponds to the JSON schema field "id".
	Id string `json:"id"`

	// Modified corresponds to the JSON schema field "modified".
	Modified string `json:"modified"`

	// Published corresponds to the JSON schema field "published".
	Published *string `json:"published,omitempty"`

	// References corresponds to the JSON schema field "references".
	References []OsvSchemaReferencesElem `json:"references,omitempty"`

	// Related corresponds to the JSON schema field "related".
	Related []string `json:"related,omitempty"`

	// SchemaVersion corresponds to the JSON schema field "schema_version".
	SchemaVersion *string `json:"schema_version,omitempty"`

	// Severity corresponds to the JSON schema field "severity".
	Severity []OsvSchemaSeverityElem `json:"severity,omitempty"`

	// Summary corresponds to the JSON schema field "summary".
	Summary *string `json:"summary,omitempty"`

	// Withdrawn corresponds to the JSON schema field "withdrawn".
	Withdrawn *string `json:"withdrawn,omitempty"`
}

type OsvSchemaAffectedElem struct {
	// DatabaseSpecific corresponds to the JSON schema field "database_specific".
	DatabaseSpecific OsvSchemaAffectedElemDatabaseSpecific `json:"database_specific,omitempty"`

	// EcosystemSpecific corresponds to the JSON schema field "ecosystem_specific".
	EcosystemSpecific OsvSchemaAffectedElemEcosystemSpecific `json:"ecosystem_specific,omitempty"`

	// Package corresponds to the JSON schema field "package".
	Package *OsvSchemaAffectedElemPackage `json:"package,omitempty"`

	// Ranges corresponds to the JSON schema field "ranges".
	Ranges []OsvSchemaAffectedElemRangesElem `json:"ranges,omitempty"`

	// Versions corresponds to the JSON schema field "versions".
	Versions []string `json:"versions,omitempty"`
}

type OsvSchemaAffectedElemDatabaseSpecific map[string]interface{}

type OsvSchemaAffectedElemEcosystemSpecific map[string]interface{}

type OsvSchemaAffectedElemPackage struct {
	// Ecosystem corresponds to the JSON schema field "ecosystem".
	Ecosystem string `json:"ecosystem"`

	// Name corresponds to the JSON schema field "name".
	Name string `json:"name"`

	// Purl corresponds to the JSON schema field "purl".
	Purl *string `json:"purl,omitempty"`
}

type OsvSchemaAffectedElemRangesElem struct {
	// DatabaseSpecific corresponds to the JSON schema field "database_specific".
	DatabaseSpecific OsvSchemaAffectedElemRangesElemDatabaseSpecific `json:"database_specific,omitempty"`

	// Events corresponds to the JSON schema field "events".
	Events []OsvSchemaAffectedElemRangesElemEventsElem `json:"events"`

	// Repo corresponds to the JSON schema field "repo".
	Repo *string `json:"repo,omitempty"`

	// Type corresponds to the JSON schema field "type".
	Type OsvSchemaAffectedElemRangesElemType `json:"type"`
}

type OsvSchemaAffectedElemRangesElemDatabaseSpecific map[string]interface{}

type OsvSchemaAffectedElemRangesElemEventsElem map[string]interface{}

type OsvSchemaAffectedElemRangesElemType string

const OsvSchemaAffectedElemRangesElemTypeECOSYSTEM OsvSchemaAffectedElemRangesElemType = "ECOSYSTEM"
const OsvSchemaAffectedElemRangesElemTypeGIT OsvSchemaAffectedElemRangesElemType = "GIT"
const OsvSchemaAffectedElemRangesElemTypeSEMVER OsvSchemaAffectedElemRangesElemType = "SEMVER"

type OsvSchemaCreditsElem struct {
	// Contact corresponds to the JSON schema field "contact".
	Contact []string `json:"contact,omitempty"`

	// Name corresponds to the JSON schema field "name".
	Name string `json:"name"`
}

type OsvSchemaDatabaseSpecific map[string]interface{}

type OsvSchemaReferencesElem struct {
	// Type corresponds to the JSON schema field "type".
	Type OsvSchemaReferencesElemType `json:"type"`

	// Url corresponds to the JSON schema field "url".
	Url string `json:"url"`
}

type OsvSchemaReferencesElemType string

const OsvSchemaReferencesElemTypeADVISORY OsvSchemaReferencesElemType = "ADVISORY"
const OsvSchemaReferencesElemTypeARTICLE OsvSchemaReferencesElemType = "ARTICLE"
const OsvSchemaReferencesElemTypeFIX OsvSchemaReferencesElemType = "FIX"
const OsvSchemaReferencesElemTypeGIT OsvSchemaReferencesElemType = "GIT"
const OsvSchemaReferencesElemTypePACKAGE OsvSchemaReferencesElemType = "PACKAGE"
const OsvSchemaReferencesElemTypeREPORT OsvSchemaReferencesElemType = "REPORT"
const OsvSchemaReferencesElemTypeWEB OsvSchemaReferencesElemType = "WEB"

type OsvSchemaSeverityElem struct {
	// Score corresponds to the JSON schema field "score".
	Score string `json:"score"`

	// Type corresponds to the JSON schema field "type".
	Type OsvSchemaSeverityElemType `json:"type"`
}

type OsvSchemaSeverityElemType string

const OsvSchemaSeverityElemTypeCVSSV3 OsvSchemaSeverityElemType = "CVSS_V3"

var enumValues_OsvSchemaAffectedElemRangesElemType = []interface{}{
	"GIT",
	"SEMVER",
	"ECOSYSTEM",
}
var enumValues_OsvSchemaReferencesElemType = []interface{}{
	"ADVISORY",
	"ARTICLE",
	"REPORT",
	"FIX",
	"GIT",
	"PACKAGE",
	"WEB",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaReferencesElemType) UnmarshalJSON(b []byte) error {
	var v string
	if err := json.Unmarshal(b, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_OsvSchemaReferencesElemType {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_OsvSchemaReferencesElemType, v)
	}
	*j = OsvSchemaReferencesElemType(v)
	return nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaReferencesElem) UnmarshalJSON(b []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(b, &raw); err != nil {
		return err
	}
	if v, ok := raw["type"]; !ok || v == nil {
		return fmt.Errorf("field type: required")
	}
	if v, ok := raw["url"]; !ok || v == nil {
		return fmt.Errorf("field url: required")
	}
	type Plain OsvSchemaReferencesElem
	var plain Plain
	if err := json.Unmarshal(b, &plain); err != nil {
		return err
	}
	*j = OsvSchemaReferencesElem(plain)
	return nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaCreditsElem) UnmarshalJSON(b []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(b, &raw); err != nil {
		return err
	}
	if v, ok := raw["name"]; !ok || v == nil {
		return fmt.Errorf("field name: required")
	}
	type Plain OsvSchemaCreditsElem
	var plain Plain
	if err := json.Unmarshal(b, &plain); err != nil {
		return err
	}
	*j = OsvSchemaCreditsElem(plain)
	return nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaAffectedElemRangesElem) UnmarshalJSON(b []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(b, &raw); err != nil {
		return err
	}
	if v, ok := raw["events"]; !ok || v == nil {
		return fmt.Errorf("field events: required")
	}
	if v, ok := raw["type"]; !ok || v == nil {
		return fmt.Errorf("field type: required")
	}
	type Plain OsvSchemaAffectedElemRangesElem
	var plain Plain
	if err := json.Unmarshal(b, &plain); err != nil {
		return err
	}
	*j = OsvSchemaAffectedElemRangesElem(plain)
	return nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaSeverityElemType) UnmarshalJSON(b []byte) error {
	var v string
	if err := json.Unmarshal(b, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_OsvSchemaSeverityElemType {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_OsvSchemaSeverityElemType, v)
	}
	*j = OsvSchemaSeverityElemType(v)
	return nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaAffectedElemRangesElemType) UnmarshalJSON(b []byte) error {
	var v string
	if err := json.Unmarshal(b, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_OsvSchemaAffectedElemRangesElemType {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_OsvSchemaAffectedElemRangesElemType, v)
	}
	*j = OsvSchemaAffectedElemRangesElemType(v)
	return nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaAffectedElemPackage) UnmarshalJSON(b []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(b, &raw); err != nil {
		return err
	}
	if v, ok := raw["ecosystem"]; !ok || v == nil {
		return fmt.Errorf("field ecosystem: required")
	}
	if v, ok := raw["name"]; !ok || v == nil {
		return fmt.Errorf("field name: required")
	}
	type Plain OsvSchemaAffectedElemPackage
	var plain Plain
	if err := json.Unmarshal(b, &plain); err != nil {
		return err
	}
	*j = OsvSchemaAffectedElemPackage(plain)
	return nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchemaSeverityElem) UnmarshalJSON(b []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(b, &raw); err != nil {
		return err
	}
	if v, ok := raw["score"]; !ok || v == nil {
		return fmt.Errorf("field score: required")
	}
	if v, ok := raw["type"]; !ok || v == nil {
		return fmt.Errorf("field type: required")
	}
	type Plain OsvSchemaSeverityElem
	var plain Plain
	if err := json.Unmarshal(b, &plain); err != nil {
		return err
	}
	*j = OsvSchemaSeverityElem(plain)
	return nil
}

var enumValues_OsvSchemaSeverityElemType = []interface{}{
	"CVSS_V3",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *OsvSchema) UnmarshalJSON(b []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(b, &raw); err != nil {
		return err
	}
	if v, ok := raw["id"]; !ok || v == nil {
		return fmt.Errorf("field id: required")
	}
	if v, ok := raw["modified"]; !ok || v == nil {
		return fmt.Errorf("field modified: required")
	}
	type Plain OsvSchema
	var plain Plain
	if err := json.Unmarshal(b, &plain); err != nil {
		return err
	}
	*j = OsvSchema(plain)
	return nil
}
